import type { AxiosRequestConfig, AxiosInstance } from 'axios'
import axios from 'axios'
// import router from '~/router'
import store from '~/store'
import { Base64 } from 'js-base64'
import { ElNotification } from 'element-plus'
import defaultSettings from '~/defaultSettings'
// import { serialize } from '~/utils/util'
import { getToken } from '~/utils/auth'
// import { getStore } from '~/utils/store'

// 是否401 如果是则在response弹ElNotification阻止
let flag401 = false

class Request {
  // axios 实例
  axiosInstance: AxiosInstance
  isShowError: boolean

  constructor() {
    this.isShowError = true
    this.axiosInstance = axios.create({
      // 多久超时
      timeout: 30000,
      // 跨域请求，允许保存cookie
      withCredentials: true,
      // 返回其他状态码
      validateStatus: function (status) {
        return status >= 200 && status < 500 // default
      }
    })

    // HTTPrequest拦截
    this.axiosInstance.interceptors.request.use(
      (config: AxiosRequestConfig) => {
        // 当是401时 且不是登陆页的请求 终止其他的请求
        if (flag401 && location.pathname !== defaultSettings.loginUrl) {
          config.cancelToken = new axios.CancelToken((cancel) => {
            cancel('401')
          })
        }
        // 增加延迟比较
        // const timer = setTimeout(() => {
        //   if (
        //     !handleStopRepeatRequest(
        //       requestList,
        //       config?.params
        //         ? `${config.url!}?${new URLSearchParams(config?.params).toString()}`
        //         : config.url!
        //     )
        //   ) {
        //     ElNotification({
        //       title: '系统提示',
        //       message: '请求速度过快请稍后再试',
        //       type: 'warning'
        //     })
        //     config.cancelToken = new axios.CancelToken((cancel) => {
        //       cancel('请求速度过快请稍后再试')
        //     })
        //   }
        //   clearTimeout(timer)
        // }, 1000)

        config.headers!.Authorization = `Basic ${Base64.encode(
          `${defaultSettings.clientId}:${defaultSettings.clientSecret}`
        )}`
        if (getToken()) {
          // 让每个请求携带token--['Authorization']为自定义key 请根据实际情况自行修改
          config.headers!['gxsaas-Auth'] = `bearer ${getToken()}`
        }
        return config
      },
      (error) => {
        return Promise.reject(error)
      }
    )

    // HTTPresponse拦截
    this.axiosInstance.interceptors.response.use(
      (response) => {
        const status = response.status
        const success = response.data.success
        const statusWhiteList = defaultSettings.statusWhiteList || []
        const message = response.data.msg || '未知错误'

        // 如果在白名单里则自行catch逻辑处理
        if (statusWhiteList.includes(status)) return Promise.reject(response)

        if (!success && !flag401) {
          if (this.isShowError) {
            if (response?.request.responseType === 'blob') {
              const reader = new FileReader()
              reader.addEventListener('loadend', () => {
                const data = JSON.parse(reader.result as string)
                const errorText = data?.msg || response.statusText
                ElNotification({
                  title: '系统提示',
                  message: errorText,
                  type: 'warning'
                })
              })
              reader.readAsText(response.data, 'utf-8')
            } else {
              // 如果请求为非200否者默认统一处理
              ElNotification({
                title: '系统提示',
                message,
                type: 'warning'
              })
            }
          }
        } else {
          return response
        }
        // 如果是401则跳转到登录页面
        if (status === 401) flag401 = true
        if (status === 401 && flag401) {
          store.dispatch('user/FedLogOut').then(() => {
            const timer = setTimeout(() => {
              flag401 = false
              clearTimeout(timer)
            }, 2000)
          })
        }
        return response
      },
      (error) => {
        // 排除401多余的报错提示
        if (error.name !== 'CanceledError' && error.message !== '401')
          ElNotification({
            title: '系统提示',
            message: error?.response?.data?.msg || '未知错误',
            type: 'warning'
          })
        return error
      }
    )
  }

  request(config: AxiosRequestConfig, showError?: boolean) {
    this.isShowError = showError ?? true
    return this.axiosInstance.request(config)
  }
}

function request(config: AxiosRequestConfig, showError?: boolean) {
  return new Request().request(config, showError)
}

export default request
